/*
 *  Copyright (C) 2012 Компания ВИТ. web: http://diasled.ru Е-mail:  vit@diasled.ru
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 * 
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 * 
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
 * 
 */
package ru.vit.cfgreader;

import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.ArrayList;

/**
 * 
 * @author vitekenator
 */
public class CfgReader {

    private Insoles stelki;
    private File file;
    private DataInputStream input;

    public CfgReader(File file, Insoles stelki) throws FileNotFoundException {
        this.stelki = stelki;
        this.file = file;
        this.input = new DataInputStream(new FileInputStream(this.file));
    }

    //чтение *.cfg файла
    public void readCfg() throws IOException {
        //имя файла тарировки (не где не используется)
        input.skipBytes(30);

        //имя файла нулей (не где не используется)
        input.skipBytes(30);

        //тип системы (не где не используется)
        input.skipBytes(2);

        //служебная информация (имя системы) (не где не используется)
        input.skipBytes(30);

        //количество логических номеров (максимальный номер данных для датчиков)
        stelki.setSensorsLogicalQuantity(readShort());

        //количество датчиков (для ускорения можно тут создовать коллекцию датчиков и указывать размер) 
        stelki.setSensorsQuantity(readShort());

        //таблица логических номеров
        ArrayList<Sensor> sensorCol = new ArrayList<Sensor>();
        for (int i = 0; i < stelki.getSensorsQuantity(); i++) {
            //присваиваем датчика их id
            sensorCol.add(new Sensor(readShort()));
        }
        stelki.setSensors(sensorCol);

        // гистограммы и дополнительные коэффициенты, они нам не нужны (не где не используются)
        short gist = readShort();				//признак вывода гистограмм на развертку
        if (gist == 1) {
            short countGistB = readShort();		//количество гистограмм на развертке
            input.skipBytes(14 * countGistB);	//пропускаем
        }
        short countGistG = readShort();			//количество гистограмм
        input.skipBytes(14 * countGistG);		//пропускаем
        input.skipBytes(6 * stelki.getSensorsQuantity());	//пропускаем
        input.skipBytes(24);					//пропускаем

        //максимальное давление тарировки
        stelki.setMaxPressure(readShort());

        //коэффициент пересчета веса
        stelki.setWeightCoeff(readDouble());

        //выставляем номер и координаты датчикам
        for (int i = 0; i < stelki.getSensors().size(); i++) {
            //записываем х координату
            stelki.getSensors().get(i).setX((float) readDouble());
            //записываем y координату
            stelki.getSensors().get(i).setY((float) readDouble());
            //записываем номер
            stelki.getSensors().get(i).setNumber(i + 1);
        }
        input.close();
    }

    // чтение *.ctr файла(файл контура)
    public void readCtr() throws FileNotFoundException, IOException {
        String ctrPath = file.getAbsolutePath();
        ctrPath = ctrPath.substring(0, ctrPath.lastIndexOf(".")) + ".ctr";
        input = new DataInputStream(new FileInputStream(ctrPath));

        // signature
        input.skipBytes(2);

        // version
        input.skipBytes(2);

        //contours quantity, вообще у нас их всегда 2, просто предпологалось, что будут еще.
        short contoursQuantity = readShort();

        // read contours
        // ArrayList<ContourPoint> contour = new ArrayList<>(); контуры объединятся и будут равны
        // ContourPoint point = new ContourPoint(); ошибка. так нельзя, иначе просто все точки будут читаться в один класс
        for (int i = 0; i < contoursQuantity; i++) {
            ArrayList<ContourPoint> contour = new ArrayList<>();
            //номер контура
            input.skipBytes(2);
            // количество точек в контуре
            int pointsInContour = readShort();
            for (int j = 0; j < pointsInContour; j++) {
                final ContourPoint point = new ContourPoint(); // так можно
                point.setX(readShort());
                point.setY(readShort());
                contour.add(point);
            }
            if (i == 0) {
                stelki.setLeftContour(contour);
            } else {
                stelki.setRightContour(contour);
            }
        }
        input.close();
    }

    // чтение *.tar файла
    public void readTar() throws FileNotFoundException, IOException {
        String tarPath = file.getAbsolutePath();
        tarPath = tarPath.substring(0, tarPath.lastIndexOf(".")) + ".tar";
        input = new DataInputStream(new FileInputStream(tarPath));

        //читаем тарировочные графики для каждого датчика
        float tarCoeff = stelki.getMaxPressure() / 255f;
        int[] tarData = new int[256];
        for (int i = 0; i < stelki.getSensorsQuantity(); i++) {
            for (int j = 0; j < 256; j++) {
                tarData[j] = (int) (tarCoeff * (float) input.readUnsignedByte() + 0.5f);
            }
            stelki.getSensors().get(i).setTarData(tarData);
        }

        // try to read coefficients (коэффициенты смещения и уселения)
        short[] coeff;
        int coeffSize = readShort();
        System.out.println(coeffSize);
        if (coeffSize > 0) {
            coeff = new short[coeffSize];
            for (int i = 0; i < coeffSize; i++) {
                coeff[i] = readShort();
            }
            stelki.setCoeff(coeff);
        }
        input.close();
    }

    private short readShort() throws IOException {
        byte s[] = new byte[2];
        input.read(s, 0, 2);
        ByteBuffer b = ByteBuffer.wrap(s);
        b.order(ByteOrder.LITTLE_ENDIAN);
        return b.getShort();
    }

    private double readDouble() throws IOException {
        byte s[] = new byte[8];
        input.read(s, 0, 8);
        ByteBuffer b = ByteBuffer.wrap(s);
        b.order(ByteOrder.LITTLE_ENDIAN);
        return b.getDouble();
    }

    public static void main(String[] args) throws FileNotFoundException, IOException {
        //test
        Insoles system = new Insoles();
        CfgReader test = new CfgReader(new File("S1290859.cfg"), system);
        test.readCfg();
        test.readCtr();
        test.readTar();
        
        System.out.println("c= " +system.getCoeff().length);
    }
}
